package robocup.component.coach;

import java.util.LinkedList;

import robocup.component.CoachAgent;
import robocup.component.infotypes.AuralInfo;
import robocup.component.infotypes.CoachSayInfo;
import robocup.component.infotypes.CoachVisualInfo;
import robocup.component.infotypes.PlayModeInfo;
import robocup.component.infotypes.PlayerSayInfo;
import robocup.component.infotypes.PlayerTypesInfo;
import robocup.component.infotypes.RefereeInfo;
import robocup.component.infotypes.SenseBodyInfo;
import robocup.component.infotypes.VisualInfo;
import robocup.component.speechacts.coachlanguage.DefineMessage;

public class OLCoachTactic
    implements CoachInfoReceiver {

  // The Agent
  private CoachAgent               parent;

  private CoachWorld               cwm;

  private CoachProphet             cp;

  // This Object is for coordinate sending of Messages
  private BroadcastCommand         bc;

  private final LinkedList<CoachInfoReceiver> visualInfo = new LinkedList<CoachInfoReceiver>();

  private final LinkedList<CoachInfoReceiver> auralInfo  = new LinkedList<CoachInfoReceiver>();

  private final LinkedList<CoachInfoReceiver> ptypeInfo  = new LinkedList<CoachInfoReceiver>();

  public OLCoachTactic(
      final CoachAgent parent) {

    super();
    this.parent = parent;

    this.cwm = parent.getCoachWorld();
    this.cp = new CoachProphet(this);
    this.bc = new BroadcastCommand(this);
    this.visualInfo.add(this.bc);
    this.auralInfo.add(this.bc);

    final PositionAnalyzer pa = new PositionAnalyzer(this);
    this.visualInfo.add(pa);

    final PlayerTypeAnalyzer pta = new PlayerTypeAnalyzer(this);
    this.auralInfo.add(pta);
    this.ptypeInfo.add(pta);
    this.visualInfo.add(pta);
    
    final OpponentPTypeAnalyzer oa = new OpponentPTypeAnalyzer(this);
    this.visualInfo.add(oa);

    // OpponentFormationAnalyzer ofa = new OpponentFormationAnalyzer(this);
    // visualInfo.add(ofa);

  }

  /**
   * Called by Perception at the arrival of a VisualInfo.
   * 
   * @param info
   */
  public void update(final CoachVisualInfo info) {

    for (final CoachInfoReceiver ir : this.visualInfo) {
      ir.update(info);
    }
  }

  /**
   * Called by Perception at the arrival of a AuralInfo.
   * 
   * @param info
   */
  public void update(final AuralInfo info) {

    for (final CoachInfoReceiver ir : this.auralInfo) {
      ir.update(info);
    }
  }

  /**
   * Called by Perception at the arrival of Player Types.
   * 
   * @param info
   */
  public void update(final PlayerTypesInfo info) {

    for (final CoachInfoReceiver ir : this.ptypeInfo) {
      ir.update(info);
    }
  }

  /**
   * This Method removes an InfoReceiver Object from specific List
   * 
   * @param CoachInfoReceiver
   */
  public void removeFromVisualList(final CoachInfoReceiver ir) {

    this.visualInfo.remove(ir);
  }

  /**
   * This Method removes an InfoReceiver Object from specific List
   * 
   * @param CoachInfoReceiver
   */
  public void removeFromAuralList(final CoachInfoReceiver ir) {

    this.auralInfo.remove(ir);
  }

  /**
   * This Method removes an InfoReceiver Object from specific List
   * 
   * @param CoachInfoReceiver
   */
  public void removeFromPtypeList(final CoachInfoReceiver ir) {

    this.ptypeInfo.remove(ir);
  }

  /**
   * This Method puts a Freeform Message into a queue of the BroadcastCommand
   * 
   * @param String
   */
  public void sendFreeform(final String str) {

    this.bc.appendFreeform(str);
  }

  /**
   * This Method puts a CLang Message into a queue of the BroadcastCommand
   * 
   * @param String
   */
  public void sendActions(final CoachSayInfo csi) {

    this.bc.appendCSI(csi);
  }

  /**
   * This Method sends a Message directly to the server. Notice: Please use
   * sendFreeform or sendActions instead! There is broadcasting of the Messages
   * guaranteed!
   * 
   * @param String
   */
  public void sendDirect(final String str) {

    this.parent.sendActions(str);
  }

  /**
   * This Method is only for the Opponent Formation Analyzer to pull the
   * messages into a queue of the BroadcastCommand
   * 
   * @param dm
   *          The define message
   * @param player
   *          The player number
   */
  public void sendOppFormation(final DefineMessage dm,
      final int player) {

    this.bc.appendOppFormation(dm, player);
  }

  /**
   * This Method returns the CoachWorld
   * 
   * @return CoachWorld
   */
  public CoachWorld getCwm() {

    return this.cwm;
  }

  /**
   * 
   * @return CoachProphet
   */
  public CoachProphet getCoachProphet() {

    return this.cp;
  }

  /* (non-Javadoc)
   * @see robocup.component.infotypes.InfoReceiver#update(robocup.component.infotypes.SenseBodyInfo)
   */
  public void update(final SenseBodyInfo info) {

    // TODO Auto-generated method stub
    
  }

  /* (non-Javadoc)
   * @see robocup.component.infotypes.InfoReceiver#update(robocup.component.infotypes.VisualInfo)
   */
  public void update(final VisualInfo info) {

    // TODO Auto-generated method stub
    
  }

  /* (non-Javadoc)
   * @see robocup.component.infotypes.InfoReceiver#update(robocup.component.infotypes.RefereeInfo)
   */
  public void update(final RefereeInfo info) {

    // TODO Auto-generated method stub
    
  }

  /* (non-Javadoc)
   * @see robocup.component.infotypes.InfoReceiver#update(robocup.component.infotypes.PlayModeInfo)
   */
  public void update(final PlayModeInfo info) {

    // TODO Auto-generated method stub
    
  }

  /* (non-Javadoc)
   * @see robocup.component.infotypes.InfoReceiver#update(robocup.component.infotypes.PlayerSayInfo)
   */
  public void update(final PlayerSayInfo info) {

    // TODO Auto-generated method stub
    
  }
}
